Intersection Type

type Combineable = number | string;
type Numernic = number | boolean;
// Universal是number
type Universal = Combineable & Numernic;
let someVal:Universal = 6



 

TIP

Combine Two Type Intersection Type相比接口继承的方式,书写更加简洁

type Admin = {
  name: string;
  privileges: string[];
};

type Employee = {
  name: string;
  startDate: Date;
};
// 结合Admin和Employee的属性
type ElevatedEmployee = Admin & Employee;

const e1: ElevatedEmployee = {
  name: "Aeroxian",
  privileges: ["create-server"],
  startDate: new Date(),
};











 







interface Admin {
  name: string;
  privileges: string[];
}

interface Employee {
  name: string;
  startDate: Date;
}

// 结合Admin和Employee的属性
interface ElevatedEmployee extends Employee, Admin {}

const e1: ElevatedEmployee = {
  name: "Aeroxian",
  privileges: ["create-server"],
  startDate: new Date(),
};












 








Type Guards

TIP

Type守卫

基本数据类型可以使用typeof

点击查看代码
type Combineable = number | string;

function add(a: Combineable, b: Combineable) {
  // type guard
  if (typeof a === "string" || typeof b === "string") {
    return a.toString() + b.toString();
  }
  // 这样这里就是number的相加了
  return a + b;
}




 





对象的属性in 是否存在判断来保证

点击查看代码
type Admin = {
  name: string;
  privileges: string[];
};

type Employee = {
  name: string;
  startDate: Date;
};

type UnknownEmployee = Employee | Admin;

function printEmployeeInfomation(emp: UnknownEmployee) {
  console.log("Name: " + emp.name);

  if ("privileges" in emp) {
    // type guard
    console.log("Privileges: " + emp.privileges);
  }

  if ("startDate" in emp) {
    console.log("startDate: " + emp.startDate);
  }
}

printEmployeeInfomation({
  name: "Aeroxian",
  privileges: ["create-server"],
  startDate: new Date(),
});
















 




 










class有构造函数,可以使用instanceof来判断

点击查看代码
class Car {
  drive() {
    console.log("Driving ... ...");
  }
}
class Truck {
  // 卡车
  drive() {
    console.log("Driving a truck... ...");
  }

  // cargo 货物
  loadCargo(amount: number) {
    console.log(`Loading ${amount} cargo... ...`);
  }
}
// 车辆
type Vehicle = Car | Truck;
const v1 = new Car();
const v2 = new Truck();

function useVehicle(vehicle: Vehicle) {
  vehicle.drive();
  // if ("loadCargo" in vehicle)
  if (vehicle instanceof Truck) {
    vehicle.loadCargo(10);
  }
}

useVehicle(v1);
useVehicle(v2);
























 







Discriminated unions

TypeScript: Documentation - Discriminated unionsopen in new window

引入了Literal type 来简化Type Guards的写法

interface Bird {
  type: "Bird";
  flyingSpeed: number;
}

interface Horse {
  type: "Horse";
  runningSpeed: number;
}

type Animal = Bird | Horse;

function moveAnimal(animal: Animal) {
  let speed;
  switch (animal.type) {
    case "Bird":
      speed = animal.flyingSpeed;
      break;
    case "Horse":
      speed = animal.runningSpeed;
  }
  console.log("Moving at speed: " + speed);
}

 




 








 


 





Type Casting

TIP

作为开发者,我们知道某个元素肯定不为null,那么可以通过!的形式告诉typescript

1️⃣ 直接在前面加上尖括号

const userInputElement = <HTMLInputElement>(
  document.getElementById("user-input")!
);
 


2️⃣ 使用as

const userInputElement = document.getElementById(
  "user-input"
)! as HTMLInputElement;


 

如开始使用

const userInputElement = document.getElementById("user-input");
// 不用!自己来检测
if (userInputElement) {
  (userInputElement as HTMLInputElement).value = "Hello TypeScript";
}



 


Index properties

// index properties
interface ErrorContainer {
  [props: string]: string;
}

const errorBag: ErrorContainer = {
  email: "Not a valid email",
  username: "Must start with a capital character"
};


 






Function overloads

type Combineable = number | string;

function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: number, b: string): string;
function add(a: string, b: number): string;
function add(a: Combineable, b: Combineable) {
  // type guard
  if (typeof a === "string" || typeof b === "string") {
    return a.toString() + b.toString();
  }
  // 这样这里就是number的相加了
  return a + b;
}

const result = add("Q10 ", "Viking");
result.split(" ");



 
 
 
 












Optional Chain

TypeScript: Documentation - Optional Chainopen in new window

TIP

Help us safely access nested properties and nested object in our object data

type UserData = {
  id: string;
  name: string;
  job?: {
    title: string;
    description: string;
  };
};

const fetchedUserData: UserData = {
  id: "u1",
  name: "Aeroxian",
  // job: { title: "Developer", description: "Keep learning" },
};

console.log(fetchedUserData?.job?.title);  // 输出: undefined















 

Nullish Coalescing

TypeScript: Documentation - Nullish Coalescingopen in new window

TIP

You can think of this feature - the ?? operator - as a way to “fall back” to a default value when dealing with null or undefined. When we write code like

const userInput = undefined;
// 存储到数据库的数据
const storeData = userInput ?? "DEFAULT";
// 相当于
let x = storeData !== null && storeData !== undefined ? storeData : "DEFAULT";